home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1993, 1994 Washington University in Saint Louis
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer. 2.
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 3. All advertising
- * materials mentioning features or use of this software must display the
- * following acknowledgement: This product includes software developed by the
- * Washington University in Saint Louis and its contributors. 4. Neither the
- * name of the University nor the names of its contributors may be used to
- * endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASHINGTON UNIVERSITY AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASHINGTON
- * UNIVERSITY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
- #include "config.h"
-
- #include <stdio.h>
- #include <errno.h>
- #include <string.h>
- #ifdef SYSSYSLOG
- #include <sys/syslog.h>
- #else
- #include <syslog.h>
- #endif
- #include <time.h>
- #include <ctype.h>
- #include <pwd.h>
- #include <grp.h>
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/file.h>
- #include <sys/param.h>
-
- #include "pathnames.h"
- #include "extensions.h"
-
- #if defined(SVR4) || defined(ISC) || defined(AMIGA)
- #include <fcntl.h>
- #endif
-
- extern char remotehost[],
- remoteaddr[],
- *aclbuf;
- extern int nameserved,
- anonymous,
- guest,
- use_accessfile;
- char Shutdown[MAXPATHLEN];
- #define MAXLINE 80
- static char incline[MAXLINE];
- int pidfd = -1;
-
- extern int fnmatch();
-
- /*************************************************************************/
- /* FUNCTION : parse_time */
- /* PURPOSE : Check a single valid-time-string against the current time */
- /* and return whether or not a match occurs. */
- /* ARGUMENTS : a pointer to the time-string */
- /*************************************************************************/
-
- int
- parsetime(char *whattime)
- {
- static char *days[] = {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Wk"};
- time_t clock;
- struct tm *curtime;
- int wday,
- start,
- stop,
- ltime,
- validday,
- loop,
- match;
-
- (void) time(&clock);
- curtime = localtime(&clock);
- wday = curtime->tm_wday;
- validday = 0;
- match = 1;
-
- while (match && isalpha(*whattime) && isupper(*whattime)) {
- match = 0;
- for (loop = 0; loop < 8; loop++) {
- if (strncmp(days[loop], whattime, 2) == NULL) {
- whattime += 2;
- match = 1;
- if ((wday == loop) | ((loop == 7) && wday && (wday < 6))) {
- validday = 1;
- }
- }
- }
- }
-
- if (strncmp(whattime, "Any", 3) == NULL) {
- validday = 1;
- whattime += 3;
- }
- if (!validday)
- return (0);
-
- if (sscanf(whattime, "%d-%d", &start, &stop) == 2) {
- ltime = curtime->tm_min + 100 * curtime->tm_hour;
- if ((start < stop) && ((ltime > start) && ltime < stop))
- return (1);
- if ((start > stop) && ((ltime > start) || ltime < stop))
- return (1);
- } else
- return (1);
-
- return (0);
- }
-
- /*************************************************************************/
- /* FUNCTION : validtime */
- /* PURPOSE : Break apart a set of valid time-strings and pass them to */
- /* parse_time, returning whether or not ANY matches occurred */
- /* ARGUMENTS : a pointer to the time-string */
- /*************************************************************************/
-
- int
- validtime(char *ptr)
- {
- char *nextptr;
- int good;
-
- while (1) {
- nextptr = strchr(ptr, '|');
- if (strchr(ptr, '|') == NULL)
- return (parsetime(ptr));
- *nextptr = '\0';
- good = parsetime(ptr);
- /* gotta restore the | or things get skipped! */
- *nextptr++ = '|';
- if (good)
- return (1);
- ptr = nextptr;
- }
- }
-
- /*************************************************************************/
- /* FUNCTION : hostmatch */
- /* PURPOSE : Match remote hostname or address against a glob string */
- /* ARGUMENTS : The string to match */
- /* RETURNS : 0 if no match, 1 if a match occurs */
- /*************************************************************************/
-
- hostmatch(char *addr)
- {
- FILE *incfile;
- char *ptr;
- int found = 0;
-
- if (addr == NULL) return(0);
-
- if (isdigit(*addr))
- return(fnmatch(addr, remoteaddr, NULL));
- else if (*addr == '/') {
- /*
- * read addrglobs from named path using similar format as addrglobs
- * in access file
- */
- if ((incfile = fopen(addr, "r")) == NULL) {
- if (errno != ENOENT) syslog(LOG_ERR,
- "cannot open addrglob file %s: %s", addr, strerror(errno));
- return(0);
- }
-
- while (!found && (fgets(incline, MAXLINE, incfile) != NULL)) {
- ptr = strtok(incline, " \t\n");
- if (ptr && hostmatch(ptr))
- found = 1;
- while (!found && ((ptr = strtok(NULL, " \t\n")) != NULL)) {
- if (ptr && hostmatch(ptr))
- found = 1;
- }
- }
- fclose(incfile);
- return(found);
- }
- else
- return(fnmatch(addr, remotehost, FNM_NOCASE));
- }
-
- /*************************************************************************/
- /* FUNCTION : acl_guestgroup */
- /* PURPOSE : If the real user is a member of any of the listed groups, */
- /* return 1. Otherwise return 0. */
- /* ARGUMENTS : pw, a pointer to the passwd struct for the user */
- /*************************************************************************/
-
- int
- acl_guestgroup(struct passwd *pw)
- {
- struct aclmember *entry = NULL;
- struct group *grp;
- int which;
- char **member;
-
- entry = (struct aclmember *) NULL;
- /* guestgroup <group> [<group> ...] */
-
- while (getaclentry("guestgroup", &entry)) {
- for (which = 0; (which < MAXARGS) && ARG[which]; which++) {
- if (!(grp = getgrnam(ARG[which])))
- continue;
- if (pw->pw_gid == grp->gr_gid)
- return (1);
- for (member = grp->gr_mem; *member; member++) {
- if (!strcmp(*member, pw->pw_name))
- return (1);
- }
- }
- }
- return (0);
- }
-
- /*************************************************************************/
- /* FUNCTION : acl_autogroup */
- /* PURPOSE : If the guest user is a member of any of the classes in */
- /* the autogroup comment, cause a setegid() to the specified */
- /* group. */
- /* ARGUMENTS : pw, a pointer to the passwd struct for the user */
- /*************************************************************************/
-
- void
- acl_autogroup(struct passwd *pw)
- {
- char class[1024];
-
- struct aclmember *entry = NULL;
- struct group *grp;
- gid_t gid;
- int which;
-
- (void) acl_getclass(class);
-
- entry = (struct aclmember *) NULL;
- /* autogroup <group> <class> [<class> ...] */
-
- while (getaclentry("autogroup", &entry)) {
- if (!ARG0 || !ARG1)
- return;
-
- grp = getgrnam(ARG0);
- if (grp) {
- gid = grp->gr_gid;
- } else {
- syslog(LOG_ERR, "autogroup: set group %s not found", ARG0);
- continue;
- }
-
- for (which = 1; (which < MAXARGS) && ARG[which]; which++) {
- if (!strcmp(ARG[which], class)) {
- pw->pw_gid = gid;
- return;
- }
- }
- }
- }
-
- /*************************************************************************/
- /* FUNCTION : acl_setfunctions */
- /* PURPOSE : Scan the ACL buffer and determine what logging to perform */
- /* for this user, and whether or not user is allowed to use */
- /* the automatic TAR and COMPRESS functions. */
- /* ARGUMENTS : pointer to buffer to class name, pointer to ACL buffer */
- /*************************************************************************/
-
- void
- acl_setfunctions(void)
- {
- char class[1024];
-
- extern int log_incoming_xfers,
- log_outbound_xfers,
- mangleopts,
- log_commands,
- lgi_failure_threshold;
-
- struct aclmember *entry = NULL;
-
- int l_compress = 0,
- l_tar = 0,
- inbound = 0,
- outbound = 0,
- which,
- set;
-
- log_incoming_xfers = 0;
- log_outbound_xfers = 0;
- log_commands = 0;
-
- (void) acl_getclass(class);
-
- entry = (struct aclmember *) NULL;
- if (getaclentry("loginfails", &entry) && ARG0 != NULL) {
- lgi_failure_threshold = atoi(ARG0);
- }
- #ifndef NO_PRIVATE
- entry = (struct aclmember *) NULL;
- if (getaclentry("private", &entry) && !strcmp(ARG0, "yes"))
- priv_setup(_PATH_PRIVATE);
- #endif /* !NO_PRIVATE */
-
- entry = (struct aclmember *) NULL;
- set = 0;
- while (!set && getaclentry("compress", &entry)) {
- if (!strcasecmp(ARG0, "yes"))
- l_compress = 1;
- for (which = 1; (which < MAXARGS) && ARG[which]; which++) {
- if (fnmatch(ARG[which], class, NULL)) {
- mangleopts |= l_compress * (O_COMPRESS | O_UNCOMPRESS);
- set = 1;
- }
- }
- }
-
- entry = (struct aclmember *) NULL;
- set = 0;
- while (!set && getaclentry("tar", &entry)) {
- if (!strcasecmp(ARG0, "yes"))
- l_tar = 1;
- for (which = 1; (which < MAXARGS) && ARG[which]; which++) {
- if (fnmatch(ARG[which], class, NULL)) {
- mangleopts |= l_tar * O_TAR;
- set = 1;
- }
- }
- }
-
- /* plan on expanding command syntax to include classes for each of these */
-
- entry = (struct aclmember *) NULL;
- while (getaclentry("log", &entry)) {
- if (!strcasecmp(ARG0, "commands")) {
- if (anonymous && strcasestr(ARG1, "anonymous"))
- log_commands = 1;
- if (guest && strcasestr(ARG1, "guest"))
- log_commands = 1;
- if (!guest && !anonymous && strcasestr(ARG1, "real"))
- log_commands = 1;
- }
- if (!strcasecmp(ARG0, "transfers")) {
- set = 0;
- if (strcasestr(ARG1, "anonymous") && anonymous)
- set = 1;
- if (strcasestr(ARG1, "guest") && guest)
- set = 1;
- if (strcasestr(ARG1, "real") && !guest && !anonymous)
- set = 1;
- if (strcasestr(ARG2, "inbound"))
- inbound = 1;
- if (strcasestr(ARG2, "outbound"))
- outbound = 1;
- if (set)
- log_incoming_xfers = inbound;
- if (set)
- log_outbound_xfers = outbound;
- }
- }
- }
-
- /*************************************************************************/
- /* FUNCTION : acl_getclass */
- /* PURPOSE : Scan the ACL buffer and determine what class user is in */
- /* ARGUMENTS : pointer to buffer to class name, pointer to ACL buffer */
- /*************************************************************************/
-
- int
- acl_getclass(char *classbuf)
- {
- int which;
- struct aclmember *entry = NULL;
-
- while (getaclentry("class", &entry)) {
- if (ARG0)
- strcpy(classbuf, ARG0);
-
- for (which = 2; (which < MAXARGS) && ARG[which]; which++) {
- if (anonymous && strcasestr(ARG1, "anonymous") &&
- hostmatch(ARG[which]))
- return (1);
-
- if (guest && strcasestr(ARG1, "guest") && hostmatch(ARG[which]))
- return (1);
-
- if (!guest && !anonymous && strcasestr(ARG1, "real") &&
- hostmatch(ARG[which]))
- return (1);
- }
- }
-
- *classbuf = (char) NULL;
- return (0);
-
- }
-
- /*************************************************************************/
- /* FUNCTION : acl_getlimit */
- /* PURPOSE : Scan the ACL buffer and determine what limit applies to */
- /* the user */
- /* ARGUMENTS : pointer class name, pointer to ACL buffer */
- /*************************************************************************/
-
- int
- acl_getlimit(char *class, char *msgpathbuf)
- {
- int limit;
- struct aclmember *entry = NULL;
-
- if (msgpathbuf)
- *msgpathbuf = NULL;
-
- /* limit <class> <n> <times> [<message_file>] */
- while (getaclentry("limit", &entry)) {
- if (!ARG0 || !ARG1 || !ARG2)
- continue;
- if (!strcmp(class, ARG0)) {
- limit = atoi(ARG1);
- if (validtime(ARG2)) {
- if (ARG3 && msgpathbuf)
- strcpy(msgpathbuf, ARG3);
- return (limit);
- }
- }
- }
- return (-1);
- }
-
- /*************************************************************************/
- /* FUNCTION : acl_deny */
- /* PURPOSE : Scan the ACL buffer and determine a deny command applies */
- /* ARGUMENTS : pointer class name, pointer to ACL buffer */
- /*************************************************************************/
-
- int
- acl_deny(char *msgpathbuf)
- {
- struct aclmember *entry = NULL;
-
- if (msgpathbuf)
- *msgpathbuf = (char) NULL;
-
- /* deny <addrglob> [<message_file>] */
- while (getaclentry("deny", &entry)) {
- if (!ARG0)
- continue;
- if (!nameserved && !strcmp(ARG0, "!nameserved")) {
- if (ARG1)
- strcpy(msgpathbuf, entry->arg[1]);
- return (1);
- }
- if (hostmatch(ARG0)) {
- if (ARG1)
- strcpy(msgpathbuf, entry->arg[1]);
- return (1);
- }
- }
- return (0);
- }
-
- /*************************************************************************/
- /* FUNCTION : acl_countusers */
- /* PURPOSE : Check the anonymous FTP access lists to see if this */
- /* access is permitted. */
- /* ARGUMENTS : none */
- /*************************************************************************/
-
- int
- acl_countusers(char *class)
- {
- int count,
- which;
- char pidfile[MAXPATHLEN];
- pid_t buf[MAXUSERS];
- #if !defined(HAVE_FLOCK) && !defined(AMIGA)
- struct flock arg;
- #endif
-
- /*
- * if pidfd was not opened previously...
- * pidfd must stay open after the chroot(~ftp)
- */
-
- sprintf(pidfile, _PATH_PIDNAMES, class);
-
- if (pidfd < 0) {
- pidfd = open(pidfile, O_RDWR | O_CREAT, 0644);
- }
-
- if (pidfd < 0) {
- syslog(LOG_ERR, "open of pid file failed: %s", strerror(errno));
- return -1;
- }
-
- #ifndef AMIGA
- #ifdef HAVE_FLOCK
- while (flock(pidfd, LOCK_EX)) {
- syslog(LOG_ERR, "sleeping: flock of pid file failed: %s",
- #else
- arg.l_type = F_WRLCK;
- arg.l_whence = arg.l_start = arg.l_len = 0;
- while ( -1 == fcntl( pidfd, F_SETLK, &arg) ) {
- syslog(LOG_ERR, "sleeping: fcntl lock of pid file failed: %s",
- #endif
- strerror(errno));
- sleep(1);
- }
- #endif
- lseek(pidfd, 0, L_SET);
-
- count = 0;
-
- if (read(pidfd, buf, sizeof(buf)) == sizeof(buf)) {
- for (which = 0; which < MAXUSERS; which++)
- if (buf[which]
- #ifndef AMIGA
- && !kill(buf[which], 0)
- #endif
- )
- count++;
- }
- #ifndef AMIGA
- #ifdef HAVE_FLOCK
- flock(pidfd, LOCK_UN);
- #else
- arg.l_type = F_UNLCK; arg.l_whence = arg.l_start = arg.l_len = 0;
- fcntl(pidfd, F_SETLK, &arg);
- #endif
- #else
- close(pidfd);
- pidfd = -1;
- #endif
- return (count);
- }
-
- /*************************************************************************/
- /* FUNCTION : acl_join */
- /* PURPOSE : Add the current process to the list of processes in the */
- /* specified class. */
- /* ARGUMENTS : The name of the class to join */
- /*************************************************************************/
-
- void
- acl_join(char *class)
- {
- int which,
- avail;
- pid_t buf[MAXUSERS];
- char pidfile[MAXPATHLEN];
- pid_t procid;
- #if !defined(HAVE_FLOCK) && !defined(AMIGA)
- struct flock arg;
- #endif
-
- /*
- * if pidfd was not opened previously...
- * pidfd must stay open after the chroot(~ftp)
- */
-
- sprintf(pidfile, _PATH_PIDNAMES, class);
-
- if (pidfd < 0) {
- pidfd = open(pidfile, O_RDWR | O_CREAT, 0644);
- }
-
- if (pidfd < 0) {
- syslog(LOG_ERR, "open of pid file failed: %s", strerror(errno));
- return;
- }
-
- #ifndef AMIGA
- #ifdef HAVE_FLOCK
- while (flock(pidfd, LOCK_EX)) {
- syslog(LOG_ERR, "sleeping: flock of pid file failed: %s",
- #else
- arg.l_type = F_WRLCK;
- arg.l_whence = arg.l_start = arg.l_len = 0;
- while ( -1 == fcntl( pidfd, F_SETLK, &arg) ) {
- syslog(LOG_ERR, "sleeping: fcntl lock of pid file failed: %s",
- #endif
- strerror(errno));
- sleep(1);
- }
- #endif
-
- procid = getpid();
-
- lseek(pidfd, 0, L_SET);
- if (read(pidfd, buf, sizeof(buf)) < sizeof(buf))
- for (which = 0; which < MAXUSERS; buf[which++] = 0)
- continue;
-
- avail = 0;
- for (which = 0; which < MAXUSERS; which++) {
- if ((buf[which] == 0)
- #ifndef AMIGA
- || (kill(buf[which], 0) == -1)
- #endif
- ) {
- avail = which;
- buf[which] = 0;
- } else if (buf[which] == procid) {
- /* already exists in pid file... */
- #ifndef AMIGA
- #ifdef HAVE_FLOCK
- flock(pidfd, LOCK_UN);
- #else
- arg.l_type = F_UNLCK; arg.l_whence = arg.l_start = arg.l_len = 0;
- fcntl(pidfd, F_SETLK, &arg);
- #endif
- #else
- close(pidfd);
- pidfd = -1;
- #endif
- return;
- }
- }
-
- buf[avail] = procid;
-
- lseek(pidfd, 0, L_SET);
- write(pidfd, buf, sizeof(buf));
- #ifndef AMIGA
- #ifdef HAVE_FLOCK
- flock(pidfd, LOCK_UN);
- #else
- arg.l_type = F_UNLCK; arg.l_whence = arg.l_start = arg.l_len = 0;
- fcntl(pidfd, F_SETLK, &arg);
- #endif
- #else
- close(pidfd);
- pidfd = -1;
- #endif
-
- }
-
- /*************************************************************************/
- /* FUNCTION : acl_remove */
- /* PURPOSE : remove the current process to the list of processes in */
- /* the specified class. */
- /* ARGUMENTS : The name of the class to remove */
- /*************************************************************************/
-
- void
- acl_remove()
- {
- char class[1024];
- int which,
- avail;
- pid_t buf[MAXUSERS];
- char pidfile[MAXPATHLEN];
- pid_t procid;
- #if !defined(HAVE_FLOCK) && !defined(AMIGA)
- struct flock arg;
- #endif
-
- if (!acl_getclass(class)) {
- return;
- }
-
- /*
- * if pidfd was not opened previously...
- * pidfd must stay open after the chroot(~ftp)
- */
-
- sprintf(pidfile, _PATH_PIDNAMES, class);
-
- if (pidfd < 0) {
- pidfd = open(pidfile, O_RDWR | O_CREAT, 0644);
- }
-
- if (pidfd < 0) {
- syslog(LOG_ERR, "open of pid file failed: %s", strerror(errno));
- return;
- }
-
- #ifndef AMIGA
- #ifdef HAVE_FLOCK
- while (flock(pidfd, LOCK_EX)) {
- syslog(LOG_ERR, "sleeping: flock of pid file failed: %s",
- #else
- arg.l_type = F_WRLCK;
- arg.l_whence = arg.l_start = arg.l_len = 0;
- while ( -1 == fcntl( pidfd, F_SETLK, &arg) ) {
- syslog(LOG_ERR, "sleeping: fcntl lock of pid file failed: %s",
- #endif
- strerror(errno));
- sleep(1);
- }
- #endif
-
- procid = getpid();
-
- lseek(pidfd, 0, L_SET);
- if (read(pidfd, buf, sizeof(buf)) < sizeof(buf))
- for (which = 0; which < MAXUSERS; buf[which++] = 0)
- continue;
-
- avail = 0;
- for (which = 0; which < MAXUSERS; which++) {
- if ((buf[which] == 0)
- #ifndef AMIGA
- || (kill(buf[which], 0) == -1)
- #endif
- ) {
- avail = which;
- buf[which] = 0;
- } else if (buf[which] == procid) {
- buf[which] = 0;
- }
- }
-
- lseek(pidfd, 0, L_SET);
- write(pidfd, buf, sizeof(buf));
- #ifndef AMIGA
- #ifdef HAVE_FLOCK
- flock(pidfd, LOCK_UN);
- #else
- arg.l_type = F_UNLCK; arg.l_whence = arg.l_start = arg.l_len = 0;
- fcntl(pidfd, F_SETLK, &arg);
- #endif
- #endif
-
- close(pidfd);
- pidfd = -1;
- }
-
- /*************************************************************************/
- /* FUNCTION : pr_mesg */
- /* PURPOSE : Display a message to the user */
- /* ARGUMENTS : message code, name of file to display */
- /*************************************************************************/
-
- int
- pr_mesg(int msgcode, char *msgfile)
- {
- FILE *infile;
- char inbuf[1024],
- outbuf[1024],
- *cr;
-
- if (msgfile && strlen(msgfile) > 0) {
- infile = fopen(msgfile, "r");
- if (infile) {
- while (fgets(inbuf, 255, infile) != NULL) {
- if ((cr = strchr(inbuf, '\n')) != NULL)
- *cr = '\0';
- msg_massage(inbuf, outbuf);
- lreply(msgcode, "%s", outbuf);
- }
- fclose(infile);
- }
- }
- }
-
- /*************************************************************************/
- /* FUNCTION : access_init */
- /* PURPOSE : Read and parse the access lists to set things up */
- /* ARGUMENTS : none */
- /*************************************************************************/
-
- void
- access_init(void)
- {
- struct aclmember *entry;
-
- if (!readacl(_PATH_FTPACCESS))
- return;
- (void) parseacl();
-
- Shutdown[0] = '\0';
- entry = (struct aclmember *) NULL;
- if (getaclentry("shutdown", &entry) && ARG0 != NULL)
- (void) strncpy(Shutdown, ARG0, sizeof(Shutdown));
-
- }
-
- /*************************************************************************/
- /* FUNCTION : access_ok */
- /* PURPOSE : Check the anonymous FTP access lists to see if this */
- /* access is permitted. */
- /* ARGUMENTS : none */
- /*************************************************************************/
-
- int
- access_ok(int msgcode)
- {
- char class[1024],
- msgfile[MAXPATHLEN];
- int limit;
-
- if (!use_accessfile)
- return (1);
-
- if (aclbuf == NULL) {
- syslog(LOG_NOTICE,
- "ACCESS DENIED (error reading access file) TO %s [%s]",
- remotehost, remoteaddr);
- return (0);
- }
- if (acl_deny(msgfile)) {
- pr_mesg(msgcode, msgfile);
- syslog(LOG_NOTICE, "ACCESS DENIED (deny command) TO %s [%s]",
- remotehost, remoteaddr);
- return (0);
- }
- /* if user is not in any class, deny access */
- if (!acl_getclass(class)) {
- syslog(LOG_NOTICE, "ACCESS DENIED (not in any class) TO %s [%s]",
- remotehost, remoteaddr);
- return (0);
- }
- /* if no limits defined, no limits apply -- access OK */
- limit = acl_getlimit(class, msgfile);
-
- if ((limit == -1) || (acl_countusers(class) < limit)) {
- acl_join(class);
- return (1);
- } else {
- syslog(LOG_NOTICE, "ACCESS DENIED (user limit %d; class %s) TO %s [%s]",
- limit, class, remotehost, remoteaddr);
- pr_mesg(msgcode, msgfile);
- return (-1);
- }
-
- /* NOTREACHED */
- }
-